<?php 

/**
 * Lo concerniente al procesamiento de pagos. Esta capa de abstraccion
 * mantiene aislado lo relacionado a operaciones con pagos.
 *
 *@author Carlo Lopez <carlo.xavier.lopez 'at' gmail 'dot' com>
 */
class ProcesamPagos
{

  /**
   * (Pre)Solicita el cobro de un pago. Solo se reserva, no se cobra, para
   * verificar que el pago es suceptible de cobrar.
   */
  public static function solicitarCobro(Pago $pago, $paquetes = array())
  {
    
  }

  /** 
   * Se cobra el pago que ha introducido el cliente, con motivo de la compra de
   * productos.
   * Para poder cobrar el pago, se debe haber reservado (presolicitado) el cobro anteriormente;
   * vea el procedimiento ProcesamPagos::solicitarCobro() en esta misma clase. 
   * Para poder cobrar el pago se deben tener en el carrito los paquetes, 
   * y solo los paquetes, para los que se ha ingresado informacion de pago.
   *
   * @param  $pago      Pago     El pago que se quiere cobrar.
   * @param  $cliente   Cliente  El cliente que ha entregado el pago.
   * @param  $paquetes  array    Los paquetes que se quieren entregar.
   *
   * @throw  sfException        En caso de error en la comunicacion con el Gateway.   
   */
  public static function efectuarCobro(Pago $pago, Cliente $cliente, $paquetes = array())
  {
    $conn = Doctrine_Manager::getInstance()->getCurrentConnection();
    try{

      $conn->beginTransaction();

      $pago->setEfectuado(true);
      $pago->save();

      $cliente->setSolvente(true);
      $cliente->save();

      $ordenes = array();
      $ordenes = Doctrine_Core::getTable('Orden')->findByPagoId($pago->getPrimaryKey());
      foreach($ordenes as $orden)
      {
        $orden->setStatus(Orden::CONFIRMADO);
        $orden->save();
        if($orden->getDespachoInmediato())
          $orden->despachar();
      }

      /*
      foreach($paquetes as $paquete)
      {
        $entregas = $paquete->getEntregas();
        foreach($entregas as $entrega)
        {
          if(null == $entrega || !$entrega->exists())
            throw new sfException('no existe la entrega');

          //$entrega->setEntregado(true); TODO: esto no ha sido entregado
          $entrega->save();
          $orden = $entrega->getOrden();
          $orden->setStatus(Orden::CONFIRMADO);
          $orden->save();
          array_push($ordenes, $orden);
        }
      }
      */

      //if(PaypalManager::getInstance()->efectuarCobro($pago, $cliente, $ordenes))
      if(!PaypalManager::efectuarCobro($pago, $cliente, $ordenes))
        throw new sfException('no se pudo completar la operacion');

      $conn->commit();
    }catch(Exception $e){
      $conn->rollback();
      throw $e;
    }
    //suponemos que la respuesta es positiva, se ha cobrado el pago!

    //1) se debe actualizar el pago, como efectuado

    //2) actualizar el cliente como solvente

    //3) actualizar la orden como confirmada

    //Doctrine_Core::getTable('Pago')->setEfectuado(true);
  }
	

}
